package com.timerecord.ui;

import com.timerecord.db.DBHelper;
import com.timerecord.entity.TimeRecord;
import com.timerecord.util.TimeUtils;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.collections.ObservableList;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.control.cell.PropertyValueFactory;
import javafx.scene.control.cell.TextFieldTableCell;
import javafx.scene.layout.*;
import javafx.stage.Stage;
import javafx.util.StringConverter;
import lombok.extern.slf4j.Slf4j;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * 主界面控制器
 * 负责展示时间记录表格、提供计时控制及数据编辑功能
 */
@Slf4j
public class MainUI {
    // 常量定义 - 提取魔法值，便于统一维护
    private static final String TIME_FORMAT = "yyyy-MM-dd HH:mm"; // 时间格式化模板
    private static final int PAGE_WIDTH = 540; // 页面长度
    private static final int PAGE_HEIGHT = 300; // 页面高度
    private static final int CATEGORY_COL_WIDTH = 70;       // 类别列宽度
    private static final int CATEGORY_COMBO_BOX_WITH = 100; // 类别下拉框宽度
    private static final int DETAILS_COL_WIDTH = 70;        // 明细列宽度
    private static final int DETAILS_COMBO_BOX_WIDTH = 100; // 明细下拉框宽度
    private static final int TIME_COL_WIDTH = 120;           // 时间列宽度
    private static final int DURATION_COL_WIDTH = 70;       // 时长列宽度
    private static final int ACTION_COL_WIDTH = 70;          // 操作列宽度
    private static final int RIGHT_BOX_WIDTH = 50;          // 右侧按钮容器宽度
    private static final String TOP_BTN_STYLE_DEFAULT = "";  // 置顶按钮默认样式
    private static final String TOP_BTN_STYLE_ACTIVE = "-fx-background-color: #4CAF50; -fx-text-fill: white;"; // 置顶激活样式
    private static final String DELETE_BTN_STYLE = "-fx-background-color: #7bbeff; -fx-text-fill: white;";   // 删除按钮样式

    // 数据层与UI数据容器
    private final DBHelper dbHelper = new DBHelper();
    private final ObservableList<TimeRecord> recordList = FXCollections.observableArrayList();
    private final ObservableList<String> categoryOptions = FXCollections.observableArrayList();
    private final ObservableList<String> detailsOptions = FXCollections.observableArrayList();
    private final SimpleDateFormat sdf = new SimpleDateFormat(TIME_FORMAT);
    private TimeRecord currentRecord; // 当前正在计时的记录

    // 表格列成员变量（提升为类属性，便于单选框控制显示/隐藏）
    private TableColumn<TimeRecord, Date> startCol;       // 开始时间列
    private TableColumn<TimeRecord, Date> endCol;         // 结束时间列
    private TableColumn<TimeRecord, String> durationCol;  // 持续时间列

    // 新增构造方法，提前初始化表格列
    public MainUI() {
        // 直接初始化列（此时还未关联表格，但列对象已创建）
        this.startCol = createStartColumn();
        this.endCol = createEndColumn();
        this.durationCol = createDurationColumn();
    }

    /**
     * 创建主界面场景
     * @param stage 主窗口
     * @return 构建完成的场景
     */
    public Scene createScene(Stage stage) {
        dbHelper.init();
        loadAllData();

        // 构建核心表格区域
        TableView<TimeRecord> tableView = createTableView();
        // 构建顶部区域（输入控件 + 置顶按钮）
        HBox topContainer = createTopContainer(stage);
        // 构建整体布局
        BorderPane root = createRootLayout(topContainer, tableView);

        // 窗口关闭时处理：自动结束当前计时
        setupStageCloseEvent(stage);

        Scene scene = new Scene(root, PAGE_WIDTH, PAGE_HEIGHT);
        scene.getStylesheets().add(getClass().getResource("/style.css").toExternalForm());
        return scene;
    }


    /**
     * 构建顶部容器（输入控件 + 置顶按钮）
     */
    private HBox createTopContainer(Stage stage) {
        HBox topContainer = new HBox();
        topContainer.setPadding(new Insets(10));
        topContainer.setSpacing(10);

        // 传递stage参数到输入网格, 左侧输入控件网格
        GridPane inputGrid = createInputGrid(stage);
        HBox rightBox = createRightBox(stage);

        topContainer.getChildren().addAll(inputGrid, rightBox);
        HBox.setHgrow(rightBox, Priority.ALWAYS); // 右侧容器占满剩余空间，实现按钮靠右

        return topContainer;
    }


    /**
     * 构建输入控件网格（类别、明细、开始/结束按钮）
     * @param stage
     */
    private GridPane createInputGrid(Stage stage) {
        GridPane inputGrid = new GridPane();
        inputGrid.setPadding(new Insets(10));
        inputGrid.setHgap(10);
        inputGrid.setVgap(15);

        // 类别选择框（可编辑）
        ComboBox<String> categoryCombo = createCategoryComboBox();
        // 明细选择框（可编辑）
        ComboBox<String> detailsCombo = createDetailsComboBox(categoryCombo);
        // 计时控制按钮
        Button startBtn = new Button("开始计时");
        Button endBtn = new Button("结束计时");
        endBtn.setDisable(true);

        setStartBtnAction(categoryCombo, detailsCombo, startBtn, endBtn);
        setEndBtnAction(categoryCombo, detailsCombo, startBtn, endBtn);

        // 传递stage参数到单选框创建方法
        HBox radioBox = createColumnControlRadioBox(stage);
        inputGrid.add(radioBox, 0, 2, 3, 1);

        inputGrid.add(new Label("类别*："), 0, 0);
        inputGrid.add(categoryCombo, 1, 0);
        inputGrid.add(new Label("明细："), 0, 1);
        inputGrid.add(detailsCombo, 1, 1);
        inputGrid.add(startBtn, 2, 0);
        inputGrid.add(endBtn, 2, 1);

        return inputGrid;
    }

    /**
     * 创建类别选择框
     * 选择类别后会联动加载对应明细选项
     */
    private ComboBox<String> createCategoryComboBox() {
        ComboBox<String> categoryCombo = new ComboBox<>(categoryOptions);
        categoryCombo.setEditable(true);
        categoryCombo.setPromptText("选择或输入类别...");
        categoryCombo.setPrefWidth(CATEGORY_COMBO_BOX_WITH);

        // 类别选择变化时，加载对应明细
        categoryCombo.setOnAction(e -> {
            String selectedCategory = categoryCombo.getValue();
            detailsOptions.clear();
            detailsOptions.addAll(dbHelper.queryDetailsByCategory(selectedCategory));
        });

        return categoryCombo;
    }


    /**
     * 创建明细选择框
     */
    private ComboBox<String> createDetailsComboBox(ComboBox<String> categoryCombo) {
        ComboBox<String> detailsCombo = new ComboBox<>(detailsOptions);
        detailsCombo.setEditable(true);
        detailsCombo.setPromptText("选择或输入明细...");
        detailsCombo.setPrefWidth(DETAILS_COMBO_BOX_WIDTH);
        return detailsCombo;
    }


    /**
     * 创建"开始计时"按钮
     */
    private void setStartBtnAction(ComboBox<String> categoryCombo, ComboBox<String> detailsCombo, Button startBtn, Button endBtn) {
        startBtn.setOnAction(e -> {
            String category = categoryCombo.getValue();
            String details = detailsCombo.getValue();

            // 校验：类别不能为空
            if (category == null || category.trim().isEmpty()) {
                showAlert("提示", "请输入类别");
                return;
            }
            // 校验：不能同时开始多个计时
            if (currentRecord != null) {
                showAlert("提示", "当前已有任务正在计时，请先结束");
                return;
            }

            // 创建并保存新记录
            currentRecord = new TimeRecord();
            currentRecord.setCategory(category.trim());
            currentRecord.setDetails(details != null ? details.trim() : "");
            currentRecord.setStartTime(new Date());
            dbHelper.saveRecord(currentRecord);

            // 更新UI状态
            startBtn.setDisable(true);
            endBtn.setDisable(false);
            detailsCombo.setDisable(true);
            categoryCombo.setDisable(true);
            loadAllData();
            log.info("=========开始计时============");
        });
    }

    /**
     * 创建"结束计时"按钮
     */
    private void setEndBtnAction(ComboBox<String> categoryCombo, ComboBox<String> detailsCombo, Button startBtn, Button endBtn) {
        endBtn.setOnAction(e -> {
            if (currentRecord == null) return;

            // 更新记录结束时间并保存
            currentRecord.setEndTime(new Date());
            currentRecord.calculateDuration();
            dbHelper.saveRecord(currentRecord);

            // 重置UI状态
            startBtn.setDisable(false);
            endBtn.setDisable(true);
            categoryCombo.setDisable(false);
            detailsCombo.setDisable(false);
            categoryCombo.setValue(null);
            detailsCombo.setValue(null);
            currentRecord = null;
            loadAllData();
            log.info("=========结束计时============");
        });
    }

    /**
     * 创建表格列控制单选框组（显示/隐藏开始时间、结束时间、持续时间列）
     * @param stage
     */
    private HBox createColumnControlRadioBox(Stage stage) {
        HBox radioBox = new HBox();
        radioBox.setSpacing(15);
        radioBox.setPadding(new Insets(5, 0, 0, 0));

        // 基础固定宽度（类别+明细+操作列 + 边距和其他控件宽度）
        final int BASE_WIDTH = CATEGORY_COL_WIDTH + DETAILS_COL_WIDTH + ACTION_COL_WIDTH;  // 200是其他固定元素宽度

        // 显示开始时间单选框
        CheckBox showStartRadio = new CheckBox("显示开始时间");
        showStartRadio.setSelected(true);

        CheckBox showEndRadio = new CheckBox("显示结束时间");
        showEndRadio.setSelected(true);

        CheckBox showDurationRadio = new CheckBox("显示持续时间");
        showDurationRadio.setSelected(true);

        // 绑定事件
        showStartRadio.setOnAction(e -> {
            if (startCol != null) {
                startCol.setVisible(showStartRadio.isSelected());
                // 计算新宽度
                int newWidth = calculateNewWindowWidth(BASE_WIDTH, showStartRadio.isSelected(),
                        showEndRadio.isSelected(), showDurationRadio.isSelected());
                stage.setWidth(newWidth);
            }
        });

        // 显示结束时间单选框
        showEndRadio.setOnAction(e -> {
            if (endCol != null) {
                endCol.setVisible(showEndRadio.isSelected());
                int newWidth = calculateNewWindowWidth(BASE_WIDTH, showStartRadio.isSelected(),
                        showEndRadio.isSelected(), showDurationRadio.isSelected());
                stage.setWidth(newWidth);
            }
        });

        // 显示持续时间单选框
        showDurationRadio.setOnAction(e -> {
            if (durationCol != null) {
                durationCol.setVisible(showDurationRadio.isSelected());
                int newWidth = calculateNewWindowWidth(BASE_WIDTH, showStartRadio.isSelected(),
                        showEndRadio.isSelected(), showDurationRadio.isSelected());
                stage.setWidth(newWidth);
            }
        });

        showStartRadio.setStyle("-fx-font-size: 12px;");
        showEndRadio.setStyle("-fx-font-size: 12px;");
        showDurationRadio.setStyle("-fx-font-size: 12px;");

        radioBox.getChildren().addAll(showStartRadio, showEndRadio, showDurationRadio);
        return radioBox;
    }

    /**
     * 构建右侧容器（包含置顶按钮）
     */
    private HBox createRightBox(Stage stage) {
        HBox rightBox = new HBox();
        rightBox.setAlignment(Pos.CENTER_RIGHT);
        rightBox.setPrefWidth(RIGHT_BOX_WIDTH);

        Button topBtn = new Button("置顶");
        topBtn.setStyle("-fx-padding: 5 10;");

        // 置顶功能逻辑：切换窗口置顶状态
        topBtn.setOnAction(e -> {
            boolean isTop = stage.isAlwaysOnTop();
            stage.setAlwaysOnTop(!isTop);
            topBtn.setText(isTop ? "置顶" : "取消置顶");
            topBtn.setStyle(isTop ? TOP_BTN_STYLE_DEFAULT : TOP_BTN_STYLE_ACTIVE);
        });

        rightBox.getChildren().add(topBtn);
        return rightBox;
    }


    /**
     * 构建主表格（包含所有数据列和操作列）
     */
    private TableView<TimeRecord> createTableView() {
        TableView<TimeRecord> tableView = new TableView<>();
        tableView.setItems(recordList);
        tableView.setEditable(true);

        // 直接使用构造方法中已初始化的列，不再重新创建
        TableColumn<TimeRecord, String> categoryCol = createCategoryColumn();
        TableColumn<TimeRecord, String> detailsCol = createDetailsColumn();
        TableColumn<TimeRecord, Void> actionCol = createActionColumn();

        // 添加列到表格
        tableView.getColumns().addAll(
                categoryCol, detailsCol, startCol, endCol, durationCol, actionCol
        );

        return tableView;
    }


    /**
     * 创建类别列（支持编辑）
     */
    private TableColumn<TimeRecord, String> createCategoryColumn() {
        TableColumn<TimeRecord, String> categoryCol = new TableColumn<>("类别");
        categoryCol.setCellValueFactory(new PropertyValueFactory<>("category"));
        categoryCol.setPrefWidth(CATEGORY_COL_WIDTH);
        categoryCol.setCellFactory(TextFieldTableCell.forTableColumn());

        // 编辑提交后更新数据库
        categoryCol.setOnEditCommit(e -> {
            TimeRecord editedRecord = e.getRowValue();
            editedRecord.setCategory(e.getNewValue());
            if (editedRecord.getEndTime() != null) {
                editedRecord.calculateDuration(); // 若有结束时间，重新计算时长
            }
            dbHelper.updateRecord(editedRecord);
            loadAllData();
        });

        return categoryCol;
    }


    /**
     * 创建明细列（支持编辑）
     */
    private TableColumn<TimeRecord, String> createDetailsColumn() {
        TableColumn<TimeRecord, String> detailsCol = new TableColumn<>("明细");
        detailsCol.setCellValueFactory(new PropertyValueFactory<>("details"));
        detailsCol.setPrefWidth(DETAILS_COL_WIDTH);
        detailsCol.setCellFactory(TextFieldTableCell.forTableColumn());

        detailsCol.setOnEditCommit(e -> {
            TimeRecord editedRecord = e.getRowValue();
            editedRecord.setDetails(e.getNewValue());
            dbHelper.updateRecord(editedRecord);
            loadAllData();
        });

        return detailsCol;
    }


    /**
     * 创建开始时间列（支持编辑，时间格式校验）
     */
    private TableColumn<TimeRecord, Date> createStartColumn() {
        TableColumn<TimeRecord, Date> startCol = new TableColumn<>("开始时间");
        startCol.setCellValueFactory(new PropertyValueFactory<>("startTime"));
        startCol.setPrefWidth(TIME_COL_WIDTH);
        startCol.setCellFactory(TextFieldTableCell.forTableColumn(createTimeConverter(false)));

        startCol.setOnEditCommit(e -> {
            TimeRecord editedRecord = e.getRowValue();
            editedRecord.setStartTime(e.getNewValue());
            if (editedRecord.getEndTime() != null) {
                editedRecord.calculateDuration();
            }
            dbHelper.updateRecord(editedRecord);
            loadAllData();
        });

        return startCol;
    }


    /**
     * 创建结束时间列（支持编辑，允许为空）
     */
    private TableColumn<TimeRecord, Date> createEndColumn() {
        TableColumn<TimeRecord, Date> endCol = new TableColumn<>("结束时间");
        endCol.setCellValueFactory(new PropertyValueFactory<>("endTime"));
        endCol.setPrefWidth(TIME_COL_WIDTH);
        endCol.setCellFactory(TextFieldTableCell.forTableColumn(createTimeConverter(true)));

        endCol.setOnEditCommit(e -> {
            TimeRecord editedRecord = e.getRowValue();
            editedRecord.setEndTime(e.getNewValue());
            editedRecord.calculateDuration();
            dbHelper.updateRecord(editedRecord);
            loadAllData();
        });

        return endCol;
    }


    /**
     * 创建持续时间列（只读，格式化显示）
     */
    private TableColumn<TimeRecord, String> createDurationColumn() {
        TableColumn<TimeRecord, String> durationCol = new TableColumn<>("持续时间");
        durationCol.setPrefWidth(DURATION_COL_WIDTH);

        // 自定义显示：将秒数转换为"天-时-分-秒"格式
        durationCol.setCellValueFactory(cellData -> {
            Long seconds = cellData.getValue().getDurationSeconds();
            String formatted = TimeUtils.formatDuration(seconds);
            return new SimpleObjectProperty<>(formatted);
        });

        return durationCol;
    }


    /**
     * 创建操作列（包含删除按钮）
     */
    private TableColumn<TimeRecord, Void> createActionColumn() {
        TableColumn<TimeRecord, Void> actionCol = new TableColumn<>("操作");
        actionCol.setPrefWidth(ACTION_COL_WIDTH);

        // 自定义删除按钮单元格
        actionCol.setCellFactory(param -> new TableCell<TimeRecord, Void>() {
            private final Button deleteBtn = new Button("删除");

            {
                deleteBtn.setStyle(DELETE_BTN_STYLE);
                deleteBtn.setOnAction(e -> {
                    TimeRecord record = getTableView().getItems().get(getIndex());
                    showDeleteConfirmDialog(record);
                });
            }

            @Override
            protected void updateItem(Void item, boolean empty) {
                super.updateItem(item, empty);
                setGraphic(empty ? null : deleteBtn);
            }
        });

        return actionCol;
    }


    /**
     * 构建整体布局容器
     */
    private BorderPane createRootLayout(HBox topContainer, TableView<TimeRecord> tableView) {
        BorderPane root = new BorderPane();
        root.setTop(topContainer);
        root.setCenter(new VBox(tableView)); // 表格放在中间区域
        return root;
    }


    /**
     * 设置窗口关闭事件
     * 关闭时自动结束当前正在计时的任务
     */
    private void setupStageCloseEvent(Stage stage) {
        stage.setOnCloseRequest(e -> {
            if (currentRecord != null) {
                currentRecord.setEndTime(new Date());
                currentRecord.calculateDuration();
                dbHelper.saveRecord(currentRecord);
            }
        });
    }


    /**
     * 创建时间转换器（处理字符串与Date的转换及格式校验）
     * @param allowEmpty 是否允许空值（结束时间允许空，开始时间不允许）
     */
    private StringConverter<Date> createTimeConverter(boolean allowEmpty) {
        return new StringConverter<Date>() {
            @Override
            public String toString(Date date) {
                return date != null ? sdf.format(date) : "";
            }

            @Override
            public Date fromString(String string) {
                // 允许空值时，空字符串返回null
                if (allowEmpty && string.trim().isEmpty()) {
                    return null;
                }
                // 解析时间字符串
                try {
                    return sdf.parse(string);
                } catch (ParseException e) {
                    showAlert("格式错误", "时间格式应为：" + TIME_FORMAT);
                    return null;
                }
            }
        };
    }


    /**
     * 显示删除确认对话框
     */
    private void showDeleteConfirmDialog(TimeRecord record) {
        Alert alert = new Alert(Alert.AlertType.CONFIRMATION);
        alert.setTitle("确认删除");
        alert.setContentText("确定要删除这条记录吗？");
        alert.showAndWait().ifPresent(response -> {
            if (response == ButtonType.OK) {
                dbHelper.deleteRecord(record.getId());
                loadAllData(); // 刷新数据
            }
        });
    }


    /**
     * 加载所有数据（类别选项、记录列表、未完成记录）
     */
    private void loadAllData() {
        categoryOptions.clear();
        categoryOptions.addAll(dbHelper.queryAllCategories());

        recordList.clear();
        recordList.addAll(dbHelper.queryAllRecords());

        currentRecord = dbHelper.getLastUnfinishedRecord();
    }


    /**
     * 显示提示对话框
     */
    private void showAlert(String title, String message) {
        Alert alert = new Alert(Alert.AlertType.INFORMATION);
        alert.setTitle(title);
        alert.setContentText(message);
        alert.showAndWait();
    }

    /**
     * 计算新的窗口宽度
     */
    private int calculateNewWindowWidth(int baseWidth, boolean showStart, boolean showEnd, boolean showDuration) {
        int dynamicWidth = 0;
        if (showStart) dynamicWidth += TIME_COL_WIDTH;
        if (showEnd) dynamicWidth += TIME_COL_WIDTH;
        if (showDuration) dynamicWidth += DURATION_COL_WIDTH;
        // 确保最小宽度
        return Math.max(baseWidth + dynamicWidth, 120);
    }
}